package com.lt.integration.jpa.component;

import com.google.common.base.Strings;
import com.lt.integration.jpa.annotation.QOAttr;
import com.lt.integration.jpa.annotation.QOAttrGroup;
import com.lt.integration.jpa.annotation.QOGeo;
import com.lt.integration.jpa.annotation.QOGeoDistance;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.util.*;

public class QOUtils {
	 /**
     * @方法功能说明：得到QO有注解的属性MAP
     * @修改者名字：zhurz
     * @修改时间：2015-3-27下午4:54:10
     * @修改内容：
     * @参数：@param qo
     * @参数：@return
     * @return:Map<String,List<Field>>
     * @throws
     */
	public static Map<String, List<Field>> getQoFieldMap(BaseQO qo) {

        Map<String, List<Field>> map = new HashMap<>();

        map.put(null, new ArrayList<>());

        List<Field> fieldList = new ArrayList<>();
        if (qo == null){
            return map;
        }

        Class<?> currentClass = qo.getClass();
        while (currentClass.getSuperclass() != null
                && !currentClass.equals(BaseQO.class)) {
            Field[] fields = currentClass.getDeclaredFields();
            fieldList.addAll(Arrays.asList(fields));
            currentClass = currentClass.getSuperclass();
        }
        
        String geoName = QOGeo.class.getSimpleName();
		String goeDistanceName = QOGeoDistance.class.getSimpleName();
		
		map.put(geoName, new ArrayList<Field>());
//		map.put(goeDistanceName, new ArrayList<Field>());

        // 检查QO属性
        for (int i = 0; i < fieldList.size(); i++) {
            Field field = fieldList.get(i);
            //取出没有QOAttr注解的属性
            if (field.getAnnotation(QOAttr.class) == null) {
                fieldList.remove(i--);
                continue;
            }
            field.setAccessible(true);
			QOAttrGroup queryAttributeGroup = field.getAnnotation(QOAttrGroup.class);
			QOGeo qoGeo = field.getAnnotation(QOGeo.class);
			QOGeoDistance qoGeoDistance = field.getAnnotation(QOGeoDistance.class);
			
			if (queryAttributeGroup != null) {
				String groupName = queryAttributeGroup.value();
				if (!map.containsKey(groupName)) {
					map.put(groupName, new ArrayList<Field>());
				}
				map.get(groupName).add(field);
			} else if (qoGeo != null) {
				map.get(geoName).add(field);
			} else if (qoGeoDistance != null) {
				QOAttr queryAttribute = field.getAnnotation(QOAttr.class);
				String key = goeDistanceName + "#" + queryAttribute.name();;
				
				List<Field> fields = new ArrayList<>();
				fields.add(field);
				map.put(key, fields);
			} else {
				map.get(null).add(field);
			}
        }

        return map;
    }
    /**
     * @方法功能说明：判断是否为true
     * @修改者名字：zhurz
     * @修改时间：2015-3-27下午4:54:37
     * @修改内容：
     * @参数：@param qo
     * @参数：@param name
     * @参数：@return
     * @return:boolean
     * @throws
     */
    public static boolean isTrue(BaseQO qo, String name) {

        if (Strings.isNullOrEmpty(name)){
            return false;
        }

        Field field = null;
        Class<?> currentClass = qo.getClass();
        while (field == null && currentClass.getSuperclass() != null && !currentClass.equals(BaseQO.class)) {
            try {
                field = currentClass.getDeclaredField(name);
            } catch (Exception e) { }
            currentClass = currentClass.getSuperclass();
        }
        if (field == null){
            return false;
        }

        if (!(field.getType().equals(Boolean.class) || field.getType().equals(boolean.class))){
            return false;
        }


        Boolean b = null;
        try {
            field.setAccessible(true);
            b = (Boolean) field.get(qo);
        } catch (Exception e) { }

        if (b == null || b == false){
            return false;
        }

        return true;
    }

    /**
     * @方法功能说明：如果是String判断是否为空
     * @修改者名字：zhurz
     * @修改时间：2015-3-27下午4:54:54
     * @修改内容：
     * @参数：@param obj
     * @参数：@return
     * @return:boolean
     * @throws
     */
    public static boolean checkIfStringBlank(Object obj) {
        if (!(obj instanceof String))
            return false;
        if (Strings.isNullOrEmpty((String) obj))
            return true;
        return false;
    }
    
    public static String getUpdateString(String template, String entityName) {

		Assert.hasText(entityName, "Entity name must not be null or empty!");

		return String.format(template, entityName);
	}
}
